package org.timeticker;

import java.util.Date;
import java.util.Calendar;
import java.util.Locale;
import java.io.ObjectOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;

/**
 * Date representation limited to the day granularity 
 *
 * @author Ivan Latysh
 * @version 0.1
 * @since 25-Aug-2007 : 6:15:49 PM
 */
public class Day extends Date implements Serializable {

  /**
   * Create a new day default to today
   */
  public Day() {
    this(System.currentTimeMillis());
  }

  /**
   * Create a new date with given time.<br/>
   * Time portion will be stripped out.
   *
   * @param date time
   */
  public Day(long date) {
    super(stripTime(date));
  }

  /**
   * Set time.<br/>
   * Time portion will be stripped out.
   *
   * @param time time in milliseconds
   */
  public void setTime(long time) {
    super.setTime(stripTime(time));
  }

  /**
   * Return time in milliseconds
   *
   * @return time
   */
  public long getTime() {
    return super.getTime();
  }

  /**
   * String time from given date
   *
   * @param date date to strip time from
   * @return date without time
   */
  private static long stripTime(long date) {
    // calculate time
    Calendar cal = Calendar.getInstance(Locale.getDefault());
    cal.setTimeInMillis(date);
    cal.add(Calendar.HOUR_OF_DAY, -cal.get(Calendar.HOUR_OF_DAY));
    cal.add(Calendar.MINUTE, -cal.get(Calendar.MINUTE));
    cal.add(Calendar.SECOND, -cal.get(Calendar.SECOND));
    cal.add(Calendar.MILLISECOND, -cal.get(Calendar.MILLISECOND));
    return cal.getTime().getTime();
  }

  /**
   * Serialize object
   *
   * @param s object output stream
   * @serialData time in milliseconds
   * @throws java.io.IOException when unable to write object
   */
  private void writeObject(ObjectOutputStream s) throws IOException {
      s.writeLong(super.getTime());
  }

  /**
   * Reconstitute this object from a stream (i.e., deserialize it).
   * @param s object input stream
   * @throws java.io.IOException when unable to read from the stream
   * @throws ClassNotFoundException when unable to construct an object
   */
  private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
      setTime(s.readLong());
  }

}
